package com.easylinkin.linkappapi.danger.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.common.service.CommonService;
import com.easylinkin.linkappapi.common.utils.excel.ExcelConstant;
import com.easylinkin.linkappapi.common.utils.excel.ExcelTools;
import com.easylinkin.linkappapi.common.utils.io.OutputStreamUtil;
import com.easylinkin.linkappapi.danger.dao.DangerTypeMapper;
import com.easylinkin.linkappapi.danger.entity.Danger;
import com.easylinkin.linkappapi.danger.entity.DangerType;
import com.easylinkin.linkappapi.danger.entity.vo.DangerTypeNode;
import com.easylinkin.linkappapi.danger.entity.vo.DangerTypeVo;
import com.easylinkin.linkappapi.danger.service.DangerService;
import com.easylinkin.linkappapi.danger.service.DangerTypeService;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.*;

/**
 * DangerType表服务实现类
 *
 * @author CodeGenerator
 * @date 2022/07/23
 */
@Slf4j
@Service("appDangerTypeService")
public class DangerTypeServiceImpl extends ServiceImpl
        <DangerTypeMapper, DangerType> implements DangerTypeService {
    @Resource
    private CommonService commonService;
    @Resource
    private LinkappUserContextProducer linkappUserContextProducer;
    @Resource
    private DangerService dangerService;


    @Override
    public boolean saveOne(DangerType appDangerType) {
//        commonService.setCreateAndModifyInfo(appDangerType);
        // appDangerType.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
//        validParamRequired(appDangerType);
//        validRepeat(appDangerType);
//        validParamFormat(appDangerType);
        saveByDangers();
        return true;
//        return save(appDangerType);
    }

    /**
     * 通过隐患 生成隐患树
     */
    private void saveByDangers() {
//        删除所有的类型
        remove(new QueryWrapper<>());
        List<Danger> dangers = dangerService.selectList(new Danger());
        Set<DangerType> dangerTypes = new LinkedHashSet<>(720);
//        Integer level = 1;
        for (int level = 1; level <= 3; level++) {
            for (Danger danger : dangers) {
                if (danger.getCode().split("\\.").length < (level + 1)) {
                    continue;
                }
                String code = getConnect(danger.getCode(), level, "\\.", ".");
                String fullname = getConnect(danger.getFullName(), level, "/", "/");
                String fullId = getConnect(danger.getFullId(), level, "/", "/");
                String name = danger.getFullName().split("/")[level - 1];
                String[] fullIds = fullId.split("/");
                int typeId;
                if (fullIds.length > 1) {
                    typeId = Integer.parseInt(fullIds[fullIds.length - 1]);
                } else {
                    typeId = Integer.parseInt(fullIds[0]);
                }
                DangerType dan = new DangerType((long) typeId, fullId, fullname, name, code, level);
                if (level == 1) {
                    dan.setParentId(1L);
                } else {
                    dan.setParentId(Long.valueOf(danger.getFullId().split("/")[level - 2]));
                }
                dangerTypes.add(dan);
            }
        }
        saveBatch(dangerTypes);
    }

    private String getConnect(String code, Integer level, String s, String s2) {
        String[] split = code.split(s);
        StringBuilder sb = new StringBuilder();
        for (Integer i = 0; i < level; i++) {
            sb.append(split[i]);
            if (i < level - 1) {
                sb.append(s2);
            }
        }
        return sb.toString();
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateOne(DangerType appDangerType) {
        Assert.notNull(appDangerType.getId(), "id不能为空");
        commonService.setModifyInfo(appDangerType);
        //appDangerType.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        validRepeat(appDangerType);
        validParamFormat(appDangerType);
        return updateById(appDangerType);
    }

    @Override
    public IPage<DangerTypeNode> selectPage(Page page, DangerType appDangerType) {
        //appDangerType.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        return baseMapper.selectPage(page, appDangerType);
    }

    @Override
    public List<DangerTypeNode> selectList(DangerType appDangerType) {
        String  tenantId = appDangerType.getTenantId();
        if(StringUtils.isBlank(tenantId)){
            appDangerType.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        }
        return baseMapper.selectPage(appDangerType);
    }

    @Override
    public List<DangerTypeNode> selectTree(DangerType dangerType) {
        List<DangerTypeNode> r = selectList(dangerType);
        return listToTree(r);
    }

    /**
     * 获取树
     * 原文链接：https://blog.csdn.net/jcroad/article/details/79735790
     *
     * 方法三
     *
     * @param list
     * @return
     */
    /**
     * 方法二、
     * @param list
     * @return
     */
    public static List<DangerTypeNode> listToTree(List<DangerTypeNode> list) {
        //用递归找子。
        List<DangerTypeNode> treeList = new ArrayList<DangerTypeNode>();
        for (DangerTypeNode tree : list) {
//            顶级
            if (tree.getParentId() == 0) {
                treeList.add(findChildren(tree, list));
            }
        }
        return treeList;
    }

    private static DangerTypeNode findChildren(DangerTypeNode tree, List<DangerTypeNode> list) {

        for (DangerTypeNode node : list) {
            if (Objects.equals(node.getParentId(), tree.getDangerTypeId())) {
            
                if (tree.getChildren() == null) {
                    tree.setChildren(new ArrayList<DangerTypeNode>());
                }
                tree.getChildren().add(findChildren(node, list));
            }
        }
        return tree;
    }



    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteByIds(List<Long> idList) {
        return removeByIds(idList);
    }

    @Override
    public void export(DangerType appDangerType, HttpServletRequest request, HttpServletResponse
            response) {

        IPage<DangerTypeNode> page = selectPage(new Page(0, -1), appDangerType);
        List<DangerTypeNode> records = page.getRecords();
        List
                <DangerTypeVo> appDangerTypeVos = new ArrayList<>();
        for (DangerType expert : records) {
            appDangerTypeVos.add(new DangerTypeVo(expert));
        }

        String keyValue = "名称:name,租户id:tenantId";
        String title = "DangerType导出数据";
        String fileName = title + ".xls";
        try {
            OutputStream outputStream = OutputStreamUtil
                    .getOutputStream(request, response, fileName);
            ExcelTools.exportExcel(outputStream, keyValue, appDangerTypeVos, ExcelConstant.XLS, title);
            response.flushBuffer();
            outputStream.close();
        } catch (IOException e) {
            log.error("excel导出失败", e);
            throw new RuntimeException("excel导出失败！IOException异常" + e.getMessage());
        } catch (Exception e) {
            log.error("excel导出失败", e);
            throw new RuntimeException("excel导出失败！" + e.getMessage());
        }
    }

    @Override
    public DangerType getOneById(Serializable id) {
        return baseMapper.getOneById(id);
    }

    /**
     * 校验重复
     */
    private void validRepeat(DangerType appDangerType) {
        /* QueryWrapper<DangerType> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("name", appDangerType.getName());
        queryWrapper.eq("tenant_id", linkappUserContextProducer.getNotNullCurrent().getTenantId());
        List<DangerType> list = baseMapper.selectList(queryWrapper);
        if (list.size() == 0) {
            return;
        }
        if (list.size() > 1) {
            throw new BusinessException("名称有重复");
        }
        if (ObjectUtils.isEmpty(appDangerType.getId())) {
            throw new BusinessException("名称已存在");
        }
        if (!appDangerType.getId().equals(list.get(0).getId())) {
            throw new BusinessException("名称已存在");
        }
                    */

    }


    /**
     * 校验参数必填
     */
    private void validParamRequired(DangerType appDangerType) {
        //Assert.notNull(appDangerType, "参数为空");
        //Assert.isTrue(StringUtils.isNotBlank(appDangerType.getName()), "名称为空");
    }

    /**
     * 校验参数格式
     */
    private void validParamFormat(DangerType appDangerType) {
        //Assert.isTrue(appDangerType.getName() == null || appDangerType.getName().length() <= 50,
        //        "名称超长");
    }

}

